//////////////////////////////////////////////////////////////////////////
//
// This file is a part of APNS provider project.
// Copyright (c) Vladimir Gumenuk, 2013-2014.
//
// PROJECT:         APNS provider
// FILE:            GMSBuffer.cpp: implementation of the CGMSBuffer class.
// AUTHOR:          Vladimir Gumenuk
// DATE:            22-Dec-2013
// MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "GMSBuffer.h"

HRESULT __stdcall CreateGMSBuffer( IGMSBuffer **ppOut )
{
    return CGMSBuffer::Create( ppOut );
}

HRESULT CGMSBuffer::Create( IGMSBuffer **ppOut )
{
    if( !ppOut )
        return E_POINTER;

    TGMSBufferImpl *p = NULL;
    HRESULT hr = TGMSBufferImpl::CreateInstance( &p );
    if( SUCCEEDED( hr ) )
    {
        p->AddRef();

        hr = p->QueryInterface( IID_IGMSBuffer, (void**)ppOut );

        p->Release();
    }

    return hr;
}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CGMSBuffer::CGMSBuffer()
{

}

CGMSBuffer::~CGMSBuffer()
{
    m_Buffer.RemoveAll();
}

STDMETHODIMP_(DWORD) CGMSBuffer::GetSize()
{
    return (DWORD)m_Buffer.GetSize();
}

STDMETHODIMP_(const LPBYTE) CGMSBuffer::GetPtr()
{
    LPBYTE pBuf = m_Buffer.GetData();
    return pBuf;
}

STDMETHODIMP CGMSBuffer::Add( const LPBYTE pBuf, DWORD dwSize )
{
    if( !pBuf )
        return E_POINTER;
    if( !dwSize )
        return E_INVALIDARG;

    HRESULT hr = S_OK;

    for( DWORD i = 0; i < dwSize; i++ )
    {
        if( !m_Buffer.Add( pBuf[i] ) )
        {
            hr = E_OUTOFMEMORY;
            break;
        }
    }

    return hr;
}

STDMETHODIMP CGMSBuffer::AddBYTE( BYTE Val )
{
    return m_Buffer.Add( Val ) ? S_OK : E_OUTOFMEMORY;
}

STDMETHODIMP CGMSBuffer::Attach( LPBYTE pBuf, DWORD dwSize )
{
    m_Buffer.RemoveAll();
    
    m_Buffer.m_aT = pBuf;
    m_Buffer.m_nSize = dwSize;
    m_Buffer.m_nAllocSize = dwSize;

    return S_OK;
}
